﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using AvalonDock;
using System.Collections.ObjectModel;
using RiskMan.Views.Stop;
using RiskMan.Views.RiskManager;
using RiskMan.Views.LimitStock;
using RiskMan.DataClass;
using RiskMan.Config;
using RiskMan.Providers.QuikIO;
using Microsoft.Win32;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
using System.Management;
using System.Windows.Media;
using RiskMan.Views.AboutFrom;
using RiskMan.Views.Dialogs;
using System.IO.IsolatedStorage;
using System.Xml;
using System.Windows.Media.Animation;
using QuikIntegration.dde;
using RiskMan.Views.RMInvestor;
using RiskMan.Views.LimitMoneyAndDeals;
using System.Windows.Threading;
using RiskMan.Views.Tables;


namespace RiskMan
{
    public partial class MainWindow : Window
    {
        public static MainWindow StaticRiskMan;
        public static int countLisence;

        private Register reg;
        public ObservableCollection<DocumentContent> MyDocuments { get; private set; }
        public Data _dataProvider;
        public QuikTerminals Terminals;
        private RiskMan.Config.History _history;
        public String path = "";
        List<string> listWindow = new List<string>();

        static public TimeSpan dd;
        TimeSpan TimeW;
        private DispatcherTimer _dsUpdate = new DispatcherTimer();

        public DateTime startNight = new DateTime();
        public DateTime endNight = new DateTime();
       
        public MainWindow()
        {
            StaticRiskMan = this;
            try
            {
                InitializeComponent();
                MyDocuments = new ObservableCollection<DocumentContent>();
                DataContext = this;

                _dataProvider = new Data();
                _dataProvider.Dispatcher = this.Dispatcher;
                _history = new RiskMan.Config.History(_dataProvider);
                _history.Load();

                QuikIntegration.dde.QuikUtil.StopDDE();
                QuikIntegration.dde.QuikUtil.StartDDE();

               mWindow.Title="Риск менеджер  v." + System.Reflection.Assembly.GetExecutingAssembly( ).GetName( ).Version;

                #region загрузка вермени и тп
                try
                {
                    MenuItem_CheckForExit.IsChecked = RiskMan.Properties.Settings.Default.CanClose;
                    DateTime startD = Properties.Settings.Default.StartDay;
                    DateTime endD = Properties.Settings.Default.EndDay;

                    DateTime startN = Properties.Settings.Default.StartNight;
                    DateTime endN = Properties.Settings.Default.EndNight;

                    Properties.Settings.Default.StartDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, startD.Hour, startD.Minute, 0);
                    Properties.Settings.Default.EndDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, endD.Hour, endD.Minute, 0);

                    Properties.Settings.Default.StartNight = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, startN.Hour, startN.Minute, 0);
                    Properties.Settings.Default.EndNight = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, endN.Hour, endN.Minute, 0);

                    this.startNight = Properties.Settings.Default.StartNight;
                    this.endNight = Properties.Settings.Default.EndNight;
                }
                catch (Exception)
                {
                    new DialogOkCancel("При инициализации произоша ошибка", "Ошибка");
                }
                #endregion

                //dd = ntp.GetNetworkTime().TimeOfDay + new TimeSpan(4, 0, 0) - DateTime.Now.TimeOfDay;               
                //_dsUpdate.Interval = TimeSpan.FromMilliseconds(1000);
                //_dsUpdate.Start();
                //_dsUpdate.Tick += new EventHandler(UpdateTime);
                
            }
            catch (Exception ex)
            {
                new DialogOkCancel("При инициализации произоша ошибка: " + ex.Source, "Ошибка");
            }


            //AppDomain currentDomain = AppDomain.CurrentDomain;
            //currentDomain.AssemblyResolve += new ResolveEventHandler((s, e) =>
            //{
            //    System.Reflection.Assembly[] asms = AppDomain.CurrentDomain.GetAssemblies();
            //    for (int i = 0; i < asms.Length; ++i)
            //    {
            //        if (asms[i].FullName == e.Name)
            //            return asms[i];
            //    }
            //    return null;
            //});


        }
        public void dockManager_Loaded(object sender, RoutedEventArgs args)
        {

        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string uid = cfg.GetID() + cfg.GetMacAddress();
            reg = new Register(uid);

            if (uid == "BFEBFBFF000206A75404A64B93E9")
                reg.IsRun = true;

            //reg.IsRun = false;
            Updater.Instance().Run(System.Reflection.Assembly.GetExecutingAssembly().GetName().Version, false);

            MenuItem_CheckUpdate.IsChecked = RiskMan.Properties.Settings.Default.CheckUpdate;

            dockManager.Loaded += new RoutedEventHandler(dockManager_Loaded);

            listWindow = GetWindow();
            foreach (var item in listWindow)
            {
                PublishNewDocument(item);
            }

            try
            {
                if (_dataProvider.T2QItems.Count <= 0)
                {
                    if ((new DialogYesNo("Вы хотите настроить соединения сейчас?", "Загрузка")).Result == MessageBoxResult.Yes)
                    {
                        CheckOpenDocument(cfg.Mainsetting);
                    }
                }
            }
            catch (Exception ex)
            {
                new DialogOkCancel(ex.ToString(), "Window_Loaded");
            }


        }

        private List<string> GetWindow()
        {
            return (List<string>)XMLHistory.GetXmlData(XMLHistory.FILENAME_WINDOW);
        }

 
        private void CreateNewDocument(object sender, RoutedEventArgs e)
        {
            CheckOpenDocument(((MenuItem)sender).Header.ToString());

        }

        /// <summary>
        /// Проверяем открытые DocumentContent и в случае отсутствия добавляем
        /// </summary>
        /// <param name="sender">name DocumentContent</param>
        private void CheckOpenDocument(string sender)
        {
            string baseDocTitle = sender;
            for (int i = 0; i < dockManager.Documents.Count; i++)
            {
                if (dockManager.Documents[i].Title == baseDocTitle)
                {
                    dockManager.Documents[i].Activate();
                    return;
                }
            }
            PublishNewDocument(baseDocTitle);
        }

        /// <summary>
        /// Open DocumentConent
        /// </summary>
        /// <param name="baseDocTitle">name DocumentContent</param>
        private void PublishNewDocument(string baseDocTitle)
        {
            #region Modules
            if (baseDocTitle == cfg.MainfunctionStop)
            {
                StopView st = new StopView() { Name = "StopViewLayout", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }
            if (baseDocTitle == cfg.MainfunctionRm)
            {
                RiskManager st = new RiskManager() { Name = "RiskManLayout", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }

            if (baseDocTitle == cfg.Mainsetting)
            {
                MainSettings uc = new MainSettings() { Name = "BasicSetting", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(uc);
                uc.Activate();
            }
            if (baseDocTitle == cfg.MainfunctionRmInvestor)
            {
                RMInvestor uc = new RMInvestor() { Name = "RiskManInvestorLayout", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(uc);
                uc.Activate();
            }

            if (baseDocTitle == cfg.MainfunctionLimitstock)
            {
                LimitStockView uc = new LimitStockView() { Name = "LimitStockViewLayout", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(uc);
                uc.Activate();
            }

            if (baseDocTitle == cfg.MainfunctionLimitmoneyanddeals)
            {
                LimitMoneyAndDeals uc = new LimitMoneyAndDeals() { Name = "LimitMoneyAndDealsViewLayout", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(uc);
                uc.Activate();
            }
            
            #endregion

            #region Tables

            if (baseDocTitle == cfg.MainMenuTtp)
            {
                CuurentParam uc = new CuurentParam() { Name = "CuurentParamViewLayout", Title = cfg.MainMenuTtp, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(uc);
                uc.Activate();
            }

            if (baseDocTitle == cfg.MainMenuOrders)
            {
                TableOrders uc = new TableOrders() { Name = "TableOrdersViewLayout", Title =cfg.MainMenuOrders, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(uc);
                uc.Activate();
            }            
            if (baseDocTitle == cfg.MainMenuLimitByAccountsFuture)
            {
                TableLimiteByAccount uc = new TableLimiteByAccount() { Name = "TableLimiteByAccount", Title = cfg.MainMenuLimitByAccountsFuture, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(uc);
                uc.Activate();
            }
            #endregion
        }

        private void ClearDocumentsList(object sender, RoutedEventArgs e)
        {
            MyDocuments.Clear();
        }


        /// <summary>
        /// Creat list documentContent for save
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            listWindow.Clear();
            foreach (var item in MyDocuments)
            {
                listWindow.Add(item.Title);
            }
            SetWindow(listWindow);
        }

        /// <summary>
        /// Save open documentContent
        /// </summary>
        /// <param name="list"></param>
        private void SetWindow(List<string> list)
        {
            XMLHistory.SetXmlData(XMLHistory.FILENAME_WINDOW, (Object)(list));
        }

        private void Button1_Click_1(object sender, RoutedEventArgs e)
        {
            if (this.Topmost == false)
            {
                this.Topmost = true;
                Button1.Style = (Style)this.Resources["TopMost_ButtonStyle"];
                cfg.SetLog(this.GetType().FullName + "." + MethodBase.GetCurrentMethod().Name + ": Свойство окна \"Поверх всех\" - поставлено", MainWindow.StaticRiskMan.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
            }
            else
            {
                this.Topmost = false;
                Button1.Style = (Style)this.Resources["TopMostOut_ButtonStyle"];
                cfg.SetLog(this.GetType().FullName + "." + MethodBase.GetCurrentMethod().Name + ": Свойство окна \"Поверх всех\" - снято", ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
            }
        }

        public void Terminals_OnTerminalsConnectionChanged(String msgError, String name, bool isConnect, object sender)
        {
            //cfg.SetLog( "Terminal:  " + name + " Connection:  " + sender.ToString( ) + ":  " + msgError, ListBox_Logs );
            if (sender.ToString() == "SUCCESS" || sender.ToString() == "QUIK_CONNECTED")
            {
                for (int i = 0; i < _dataProvider.T2QItems.Count; i++)
                {
                    if (_dataProvider.T2QItems[i].Name == name)
                        _dataProvider.T2QItems[i].IsConn = true;
                }
            }
            else
            {
                for (int i = 0; i < _dataProvider.T2QItems.Count; i++)
                {
                    if (_dataProvider.T2QItems[i].Name == name)
                        _dataProvider.T2QItems[i].IsConn = false;
                }
            }

            if (sender.ToString() == "DLL_DISCONNECTED")
            {
                cfg.SetLog(" Соединение с терминалом \"" + name + "\" потеряно", ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
                new DialogMessage("Соединение с терминалом \"" + name + "\" потеряно", "Внимание");
            }

            if (sender.ToString() == "QUIK_DISCONNECTED")
                cfg.SetLog(" Соединение терминала \"" + name + "\" с сервером отсутствует", ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());

            if (sender.ToString() == "QUIK_CONNECTED")
                cfg.SetLog(" Соединение терминала \"" + name + "\" с сервером установлено", ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());

            if (sender.ToString() == "SUCCESS")
                cfg.SetLog(" Соединение с терминалом \"" + name + "\" установлено", ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());

            if (sender.ToString() == "QUIK_TERMINAL_NOT_FOUND")
                cfg.SetLog(" Терминал \"" + name + "\" не запушен. Проверьте включены ли внешние транзакции", ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());

            Debug.Print(sender.ToString());
        }

        public void Terminals_OnTerminalsTransaction(object error, int tid, double orderId, string msgError)
        {
            //cfg.SetLog(": TId:  " + tid + "  OrderId:  " + orderId + "  Error:  " + error + " Comment:  " + msgError, ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
            //if (orderId == 0)
            //{
            //    _dataProvider.OrderBlockingItems = new OBlockingItems().ToList(_dataProvider.OrderBlockingItems.Where(a => a.TID != tid).ToList());
            //    _dataProvider.StopOrderBlockingItems = new SOBlockingItems().ToList(_dataProvider.StopOrderBlockingItems.Where(a => a.TID != tid).ToList());
            //}

        }

        public void Terminals_OnTerminalsTransactionAcc(object error, int tid, double orderId, string msgError, string acc)
        {
            //cfg.SetLog("Cчет: " + acc + ";  ID транзакции:  " + tid + ";  № заявки:  " + orderId + ";  Статус:  " + error + ";  Комментарий:  " + msgError, ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
            cfg.SetLog("Cчет: " + acc + ";  Комментарий:  " + msgError, ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
            //if (orderId == 0)
            //{
            //    _dataProvider.OrderBlockingItems = new OBlockingItems().ToList(_dataProvider.OrderBlockingItems.Where(a => a.TID != tid).ToList());
            //    _dataProvider.StopOrderBlockingItems = new SOBlockingItems().ToList(_dataProvider.StopOrderBlockingItems.Where(a => a.TID != tid).ToList());
            //}

        }

        /// <summary>
        /// создание транзакционного соединия 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void button2_Click(object sender, RoutedEventArgs e)
        {

            if (reg.IsRun == false)
            {
                if (reg.message.Length != 0)
                    new DialogOkCancel(reg.message, "Регистрация");
                else
                    new DialogOkCancel("Вы не зарегистрированы", "Регистрация");
                return;
            }

            try
            {
                if (_dataProvider.T2QItems.Count > 0)
                {
                    if (Terminals == null)
                    {
                        Terminals = new QuikTerminals(_dataProvider);
                        Terminals.OnTerminalsConnectionChanged += new QuiksStatusEventHandler(Terminals_OnTerminalsConnectionChanged);
                        Terminals.OnTerminalsTransaction += new QuiksTransEventHandler(Terminals_OnTerminalsTransaction);
                        Terminals.OnTerminalsTransactionAcc += new QuiksTransEventHandlerAcc(Terminals_OnTerminalsTransactionAcc);

                        ProcessCheck tmp = new ProcessCheck();
                        tmp.Check();

                        Terminals.Connects(this.ListBox_Logs);

                        button2.IsEnabled = false;
                        button4.IsEnabled = true;
                        MenuItem_RunConnect.IsEnabled = false;
                        MenuItem_RunDisconnect.IsEnabled = true;
                    }
                }
                else
                {
                    new DialogOkCancel("Настроеных терминалов нет. Добавьте и попробуйте снова", "Ошибка");
                }
            }
            catch (Exception ex)
            {
                cfg.SetLog(ex.Message, MainWindow.StaticRiskMan.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
            }
        }

        #region icon to tray

        private System.Windows.Forms.NotifyIcon TrayIcon = null;
        private ContextMenu TrayMenu = null;
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            createTrayIcon();
        }

        private bool createTrayIcon()
        {
            bool result = false;

            if (TrayIcon == null)
            {
                TrayIcon = new System.Windows.Forms.NotifyIcon();
                TrayIcon.Icon = RiskMan.Properties.Resources.linechart_8075;
                TrayIcon.Text = "Риск менеджер";

                TrayMenu = Grid_Temp.Resources["TrayMenu"] as ContextMenu;

                TrayIcon.Click += delegate(object sender, EventArgs e)
                {
                    if ((e as System.Windows.Forms.MouseEventArgs).Button == System.Windows.Forms.MouseButtons.Left)
                    {
                        ShowHideMainWindow(sender, null);
                    }
                    else
                    {
                        TrayMenu.IsOpen = true;
                        Activate();
                    }
                };
                result = true;
            }
            else
            {
                result = true;
            }

            TrayIcon.Visible = true;
            return result;
        }

        private void ShowHideMainWindow(object sender, RoutedEventArgs e)
        {
            TrayMenu.IsOpen = false; // спрячем менюшку, если она вдруг видима
            if (IsVisible)
            {
                Hide();
                (TrayMenu.Items[0] as MenuItem).Header = "Показать";
            }
            else
            {
                Show();
                (TrayMenu.Items[0] as MenuItem).Header = "Скрыть";
                WindowState = CurrentWindowState;
                Activate();
            }
        }

        private WindowState fCurrentWindowState = WindowState.Normal;
        public WindowState CurrentWindowState
        {
            get { return fCurrentWindowState; }
            set { fCurrentWindowState = value; }
        }

        protected override void OnStateChanged(EventArgs e)
        {
            base.OnStateChanged(e);
            if (this.WindowState == System.Windows.WindowState.Minimized)
            {
                //Hide( );
                (TrayMenu.Items[0] as MenuItem).Header = "Показать";
            }
            else
            {
                CurrentWindowState = WindowState;
            }
        }





        private bool fCanClose;
        public bool CanClose
        {
            get { return fCanClose; }
            set { fCanClose = value; }
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {

            base.OnClosing(e);
            if (RiskMan.Properties.Settings.Default.CanClose)
            {
                e.Cancel = true;
                CurrentWindowState = this.WindowState;
                (TrayMenu.Items[0] as MenuItem).Header = "Показать";

                Hide();
            }
            else
            {
                if ((new DialogYesNo("Вы действительно хотите выйти?", "Внимание!")).Result == MessageBoxResult.Yes)
                {
                    if ((new DialogYesNo("Сохранить данные?", "Внимание!")).Result == MessageBoxResult.Yes)
                    {
                        _history.Save();
                    }
                    TrayIcon.Visible = false;
                }
                else
                    e.Cancel = true;
            }
        }



        private void MenuExitClick(object sender, RoutedEventArgs e)
        {
            if ((new DialogYesNo("Вы действительно хотите выйти?", "Внимание!")).Result == MessageBoxResult.Yes)
            {
                if ((new DialogYesNo("Сохранить данные?", "Внимание!")).Result == MessageBoxResult.Yes)
                {
                    _history.Save();
                }
            }
            else
                return;

            TrayIcon.Visible = false;
            Environment.Exit(9);
            //  Close( );
        }

        #endregion

        /// <summary>
        /// Кнопка Создания вывода по dde каналам
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click_1(object sender, RoutedEventArgs e)
        {
            try
            {
                QuikUtil.StopDDE();

                _dataProvider.Clear();


                QuikUtil.StartDDE();
            }
            catch (Exception ex)
            {
                new DialogOkCancel(ex.ToString(), "button3_Click_1");
            }
        }

        private void MenuItem_SaveSettings_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _history.Save();
            }
            catch (Exception ex)
            {
                new DialogOkCancel(ex.ToString(), "MenuItem_SaveSettings_Click");
            }
        }

        private void MenuItem_CheckForExit_Click(object sender, RoutedEventArgs e)
        {
            RiskMan.Properties.Settings.Default.CanClose = MenuItem_CheckForExit.IsChecked;
            RiskMan.Properties.Settings.Default.Save();
        }

        #region Disconnect Trans2Quik
        private void button4_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_dataProvider.T2QItems.Count > 0)
                {
                    if (new DialogYesNo("Вы действительно хотите хотите разорвать \nвсе имеющиеся соединения?", "Внимание!").Result == MessageBoxResult.Yes)
                    {
                        Terminals.Disconnect();
                        Terminals = null;

                        button4.IsEnabled = false;
                        button2.IsEnabled = true;
                        MenuItem_RunConnect.IsEnabled = true;
                        MenuItem_RunDisconnect.IsEnabled = false;

                        cfg.SetLog("Все имеющиеся соединения разорваны", GetType(), MethodBase.GetCurrentMethod());
                    }
                }
                else
                {
                    new DialogOkCancel("Настроеных терминалов нет. Добавьте и попробуйте снова", "Ошибка");
                }
            }
            catch (Exception ex)
            {
                cfg.SetLog(ex.Message, MainWindow.StaticRiskMan.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
            }
        }
        #endregion

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }


        /// <summary>
        /// About form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Click_2(object sender, RoutedEventArgs e)
        {
            About about = new About();
            about.ShowDialog();
        }

        /// <summary>
        /// Предложения
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Click_3(object sender, RoutedEventArgs e)
        {
            Process.Start("http://rbkm-rm.reformal.ru");
        }

        private void MenuItem_CheckUpdate_Click(object sender, RoutedEventArgs e)
        {
            RiskMan.Properties.Settings.Default.CheckUpdate = MenuItem_CheckUpdate.IsChecked;
            RiskMan.Properties.Settings.Default.Save();

            if ((new DialogYesNo("Проверить обновление?", "Внимание")).Result == MessageBoxResult.Yes)
            {
                Updater.Instance().Run(System.Reflection.Assembly.GetExecutingAssembly().GetName().Version, true);
            }
        }

        private void MenuItem_LogFolder_Click(object sender, RoutedEventArgs e)
        {
            String path = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + "\\RiskMan\\";
            if (Directory.Exists(path))
                Process.Start("explorer", path);
        }
    }
}

#region поиск квиков на машине
//try
//{
//    ( new Thread( new ThreadStart( delegate( )
//        {
//            List<string> paths = cfg.getListPathFile( );
//            this.Dispatcher.BeginInvoke( new Action( ( ) =>
//                {
//                    _dataProvider.ListPath = paths;
//                } ) );
//        } ) )
//    {
//        Priority = ThreadPriority.Lowest
//    } ).Start( );
//}
//catch ( Exception ex )
//{
//    cfg.SetLog( "Ошибка при поиске терминалов: " + ex.ToString( ) );
//}
#endregion
